package br.com.verde.exemploteca.underscore
/*
  * Placeholder syntax like: someFunction(someArg, _, otherArg)
  is equivalent with: (arg) => someFunction(someArg, arg, otherArg)
  if the type inferencer does not have enough context information
  to infer the type, say A, of arg, then you have to help it as follows:
  (arg: A) => someFunction(someArg, arg, otherArg)
  * Comment author: Luc Duponcheel
 
  * 
  f(i, _)
  Expands to:
    arg => f(i,arg)

  g(j, f(i,_))
  Expands to:
    g(j, arg => f(i,arg))
 
  * Comment author: Arthur Peters
  */

object Placeholder {
  
  def filter(a: String, constraint: (String) => Boolean) = if(constraint(a)) println(a + " PASSED !")
                                                           else println(a + " FAILED !")
  
  def filter(a: String, i: Int, constraint: (String, Int) => Boolean) = if(constraint(a, i)) println(a + " PASSED !")
                                                           else println(a + " FAILED !")
  
  def filter(a: String, b: String, constraint: (String, String) => Boolean) = if(constraint(a, b)) println(a + " PASSED !")
                                                           else println(a + " FAILED !")
  
  def yetAnotherFilter(a: String, b: String, constraint: (String, String) => Boolean) = if(constraint(a, b)) println(a + " PASSED !")
                                                           else println(a + " FAILED !")
  def emptyStringConstraint(s: String) = s.isEmpty
  
  def startWithAConstraint(s: String) = s.charAt(0) == 'A'
  
  def tautology(s: String) = true
  
  def hasAOnPositionConstraint(s: String, i: Int) = s.charAt(i).toLowerCase == 'a'
  
  def directContainsConstraint(s1: String, s2: String) = s1 contains s2 
  
  def reverseContainsConstraint(s1: String, s2: String) = s2 contains s1 
		  
  def main(args : Array[String]) {
    filter("bcd", startWithAConstraint) // Like startWithAConstraint
    filter("bcd", tautology) // Like tautology
    println
    filter("bcd", _.charAt(0) == 'A') // Like startWithAConstraint
    filter("bcd", _ => true) // Like tautology
    println
    yetAnotherFilter("Rocha", "oc", _ contains _) // directContainsConstraint
    yetAnotherFilter("oc", "Rocha", (s1, s2) => s2 contains s1) //reverseContainsConstraint
    println
    filter("Rocha", 4, (_: String).charAt(_: Int).toLowerCase == 'a') // disambiguation
    filter("Rocha", "oc", (_: String) contains (_: String)) // disambiguation
  }
}
